using System;
using System.Collections.Generic;
using Common.Util;
using Dewin.BO.Util;
using Log.Controller;

namespace Dewin.BO.Model
{
    /// <summary>
    /// Lop dinh nghia cac domain
    /// </summary>
    public class Domain
    {
        public string Id { get; set; }
        public string Type { get; set; }
        public string Side { get; set; }
        public string Address { get; set; }

        private const string Filename = "AgentDomain.txt";
        public string PathData = "AgentDomain.txt";

        /// <summary>
        /// Lay danh sach domain theo provider, side
        /// </summary>
        /// <param name="provider"></param>
        /// <param name="side"></param>
        /// <returns></returns>
        public static List<Domain> GetDomains(string provider, string side)
        {
            var result = new List<Domain>();
            try
            {
                var list = GetDomains();
                result = list.FindAll(domain => domain.Type == provider && domain.Side == side);
            }
            catch (Exception ex)
            {
                LogController.WriteLog(System.Runtime.InteropServices.Marshal.GetExceptionCode(), ex, Network.GetLocalIp());
            }
            return result;
        }

        /// <summary>
        /// Lay danh sach tat ca domain
        /// </summary>
        /// <returns></returns>
        public static List<Domain> GetDomains()
        {
            var result = new List<Domain>();
            try
            {
                string str = IOFunctions.ReadFile(DewinConstant.PathData, Filename);

                if (!string.IsNullOrEmpty(str))
                    result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Domain>>(str);
            }
            catch (Exception ex)
            {
                LogController.WriteLog(System.Runtime.InteropServices.Marshal.GetExceptionCode(), ex, Network.GetLocalIp());
            }
            return result;
        }

        /// <summary>
        /// Ham ghi domain
        /// </summary>
        /// <param name="domain"></param>
        /// <returns></returns>
        public static bool Save(Domain domain)
        {
            try
            {
                // Neu Agent Id chua co thi khoi tao Id moi
                if (string.IsNullOrEmpty(domain.Id))
                {
                    if (!BuildNewId(domain)) return false;
                }

                // Luu list
                return Save(new List<Domain> { domain });
            }
            catch (Exception ex)
            {
                LogController.WriteLog(System.Runtime.InteropServices.Marshal.GetExceptionCode(), ex, Network.GetLocalIp());
            }
            return false;
        }

        /// <summary>
        /// Ham ghi danh sach domain
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static bool Save(List<Domain> list)
        {
            try
            {
                // Lay danh sach domain tu file
                var allList = GetDomains();

                // Xoa cac domain trong list cu ma ton tai trong list moi
                allList.RemoveAll(
                    domain => list.Exists(domain2 => domain.Id == domain2.Id || 
                        (domain.Address == domain2.Address && domain.Side == domain2.Side && domain.Type == domain2.Type)));

                // Add list moi vao
                allList.AddRange(list);

                string strData = Newtonsoft.Json.JsonConvert.SerializeObject(list);
                return IOFunctions.WriteFile(strData, DewinConstant.PathData, Filename);
            }
            catch (Exception ex)
            {
                LogController.WriteLog(System.Runtime.InteropServices.Marshal.GetExceptionCode(), ex, Network.GetLocalIp());
            }

            return false;
        }

        /// <summary>
        /// Xoa 1 domain
        /// </summary>
        /// <param name="domain"></param>
        /// <returns></returns>
        public static bool Delete(Domain domain)
        {
            return Delete(new List<Domain> { domain });
        }

        /// <summary>
        /// Xoa danh sach domain
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static bool Delete(List<Domain> list)
        {
            try
            {
                // Lay danh sach Address
                var allList = GetDomains();
                allList.RemoveAll(domain => list.Exists(domain2 => domain.Id == domain2.Id));

                // Luu list
                string strData = Newtonsoft.Json.JsonConvert.SerializeObject(list);
                return IOFunctions.WriteFile(strData, DewinConstant.PathData, Filename);
            }
            catch (Exception ex)
            {
                LogController.WriteLog(System.Runtime.InteropServices.Marshal.GetExceptionCode(), ex, Network.GetLocalIp());
            }
            return false;
        }

        /// <summary>
        /// Ham tao Id moi
        /// </summary>
        /// <param name="domain"></param>
        /// <returns></returns>
        private static bool BuildNewId(Domain domain)
        {
            try
            {
                var domains = GetDomains();

                // Neu so tai khoan agent da du thi khong tao nua
                if (domains.Count > DewinConstant.LimitDomainCount) return false;

                // Hien tai gioi han so agent la 10
                for (int i = 0; i < DewinConstant.LimitDomainCount; i++)
                {
                    // Tao Id
                    var id = String.Format(Provider.IdStructure, domain.Side, domain.Type, i);

                    // Neu agent chua co Id thi them va tra ve true
                    if (!domains.Exists(x => x.Id == id))
                    {
                        domain.Id = id;
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                LogController.WriteLog(System.Runtime.InteropServices.Marshal.GetExceptionCode(), ex, Network.GetLocalIp());
            }
            return false;
        }
    }
}
